#include "VFS_C_Interface.h"
#include "VirtualFile.h"
#include <physfs.h>
#include "StringUtil.h"

using namespace PhysFS;

extern "C" {

VFILE* CPhysFS_wfopen(const wchar_t* filename ,const wchar_t* mode)
{
	return CPhysFS_fopen(TOUTF8(filename).c_str(),TOUTF8(mode).c_str());
}

VFILE* CPhysFS_fopen(const char* filename ,const char* mode)
{
	try
	{
		return new device(fileInfo(filename,mode));
	}
	catch(std::ios_base::failure& e)
	{
		printf("IO error: %s \n",e.what());
		return NULL;
	}
}

size_t CPhysFS_fread(void* buffer, size_t size, size_t count, VFILE* file)
{
	device* dev=(device*)file;
	return dev->read((char*)buffer,size*count) / size;
}

size_t CPhysFS_fwrite(const void* buffer, size_t size, size_t count, VFILE* file)
{
	device* dev=(device*)file;
	return dev->write((char*)buffer,size*count) / size;
}

int CPhysFS_fseek(VFILE* file, long offset, int origin)
{
	device* dev=(device*)file;
	int seek;
	long expected;
	switch(origin)
	{
	case SEEK_SET:
		expected=offset;
		seek=std::ios_base::beg;
	break;
	case SEEK_CUR:
		expected=dev->tell()+offset;
		seek=std::ios_base::cur;
	break;
	case SEEK_END:
		expected=dev->size()-offset-1;
		seek=std::ios_base::end;
	break;
	}
	return (dev->seek(offset,seek)==expected?0:1);
}

long int CPhysFS_ftell(VFILE* file)
{
	device* dev=(device*)file;
	return dev->tell();
}

int CPhysFS_fflush(VFILE* file)
{
	device* dev=(device*)file;
	return (dev->flush()?0:EOF);
}

int CPhysFS_fclose(VFILE* file)
{
	device* dev=(device*)file;
	dev->close();
	delete (dev);
	return 0;
}

int CPhysFS_feof(VFILE* file)
{
	device* dev=(device*)file;
	return dev->eof();
}

}